﻿using System;
using System.ServiceModel;

namespace Sunyi.Project.WebPoint.ServiceAccess
{
    public abstract class WebPointServiceProxy<T> : IDisposable where T : class
    {
        private ChannelFactory<T> factory;

        protected ChannelFactory<T> Factory
        {
            get
            {
                if (factory == null) factory = new ChannelFactory<T>(this.ClientEndPointName);

                return factory;
            }
        }

        protected abstract string ClientEndPointName
        {
            get;
        }

        protected T CreateChannel()
        {
            return this.Factory.CreateChannel();
        }

        protected void Invoke(T channel, Action action)
        {
            try
            {
                action.Invoke();
            }
            finally
            {
                this.Release(channel);
            }
        }

        public void Dispose()
        {
            if (factory != null)
            {
                factory.Close();
                factory = null;
            }
        }

        private void Release(object channel)
        {
            var serviceChannel = channel as ICommunicationObject;

            if (serviceChannel != null)
            {
                try
                {
                    if (serviceChannel.State == CommunicationState.Faulted)
                    {
                        serviceChannel.Abort();
                    }
                    else
                    {
                        serviceChannel.Close();
                    }
                }
                catch
                {
                    // Nothing to do here.
                }
            }
        }
    }
}
